import React, { useMemo, useState, useEffect } from 'react';
import { useHigh, BtSwitch, obj_str, loc_str, FindBarBase, useCmd, WaitUmd, MainView, cline,
    uJob, save_data, Btn, d_sort, filter_row, GridTable, uReal, is_empty, loc } from 'sui';
import { get_init } from 'trace/cmd';
import { utc_offset } from 'cache';
import { set_tp } from './cmd';
import { User } from 'cache';

const GatherView = ({ mod, sideopen }) => {
    const [main, setMain] = useState();
    const [cur_tp, curTp] = useState();
    const [pbox, setPbox] = useState(false);
    const [opt_find, optFind] = useState();
    const umd = useCmd(null, "trace");
    const [high] = useHigh(208, 100);

    useEffect(() => get_init(optFind), []);

    const filteredRows = useMemo(() => {
        if (is_empty(main)) {
            return null;
        }

        const lst = ["sn", "width", "dt", "dia"];

        return filter_row(main, lst, umd.filter);
    }, [main, umd.filter]);

    const do_psn = (cmd, tp) => {
        umd.startWait();

        set_tp(cmd);

        uJob(null, "work/batch", cmd,
            r => {
                d_sort(r, "sn");

                r.forEach((d, i) => {
                    d["index"] = i + 1;
                    if (tp === "in") {
                        d["dia"] = d["india"];
                        d["dt"] = d["indt"];
                        d["width"] = d["inwidth"];
                    } else {
                        d["dia"] = d["outdia"];
                        d["dt"] = d["outdt"];
                        d["width"] = d["outwidth"];
                    }
                });

                setMain(r);

                umd.endWait();
            },
            e => {
                setMain(null);
                umd.endWait();
            });
    };

    const do_pbox = (cmd, tp) => {
        umd.startWait();

        uReal(null, "pair/pbox",
            {
                line: cline(),
                usn: User.userName(),
            },
            r => {
                const set = new Set();

                if (tp === "in") {
                    if (r.inner) {
                        r.inner.forEach(d => set.add(d));
                    }
                } else if (tp === "out") {
                    if (r.outer) {
                        r.outer.forEach(d => set.add(d));
                    }
                }

                if (set.size <= 0) {
                    umd.endWait();
                    return;
                }

                set_tp(cmd);

                uJob(null, "work/batch", cmd,
                    r => {
                        const tmp = r.filter(d => set.has(d.sn));

                        d_sort(tmp, "sn");
                        tmp.forEach((d, i) => d["index"] = i + 1);

                        setMain(tmp);

                        umd.endWait();
                    },
                    e => {
                        setMain(null);
                        umd.endWait();
                    });

            },
            e => umd.setErr(loc("l_803")));
    };

    const hfind = (value) => {
        const herr = (e) => {
            alert(`${loc("l_307")}: ${e}`);
        };

        if (!value["time"]) {
            herr(loc("l_308"));
            return;
        }

        const tp = obj_str(value, "tp");
        if (!tp) {
            herr(loc("l_229"));
            return;
        }

        const utc = utc_offset();
        curTp(tp);

        const opt = [
            {ge: "time", v: loc_str(value["t_start"]), utc: utc},
            {le: "time", v: loc_str(value["t_end"]), utc: utc},
            {eq: "line", v: cline()},
        ];

        const psn = obj_str(value, "psn");

        const cmd = {
            line: cline(),
            bsn: psn,
            tp: tp,
            opt: {
                desc: true,
                and: opt,
            }
        };

        if (pbox) {
            do_pbox(cmd, tp);
            return;
        }

        if (!psn) {
            herr(loc("l_488"));
            return;
        }

        do_psn(cmd, tp);
    };

    const hclear = () => get_init(optFind);

    const lst = [
        { id: "in", des: loc("l_808") },
        { id: "out", des: loc("l_809") },
    ];

    const ctl = {
        ctl: [
            {sn: "psn", name: loc("l_488")},
            {sn: "tp", name: loc("l_229"), ctl: "IkSelect", lst: lst},
            {sn: "time", name: loc("l_308"), ctl: "IkFindDate", start: "t_start", end: "t_end"},
        ]
    };

    const col = [
        {name: loc("l_193"), key: 'index', width: 70},
        {name: loc("l_810"), key: 'sn', width: 100},
        {name: loc("l_805"), key: 'width', width: 100},
        {name: loc("l_806"), key: 'dt', width: 100},
        {name: loc("l_807"), key: 'dia', width: 100},
        {name: loc("l_177"), key: 'tsn', width: 200},
    ];

    const hout = () => {
        const f = lst.find(d => d.id === cur_tp);
        if (!f) {
            return;
        }

        const name = obj_str(f, "des");

        save_data(main, col, name, umd);
    };

    const Right = () => (
        <div className="inline-flex mr-3 items-center">
            <BtSwitch checked={pbox} hcmd={setPbox} name="gc" className="ml-2">{loc("l_799")}</BtSwitch>
            <Btn className="ml-4" hcmd={hout}>{loc("l_298")}</Btn>
        </div>
    );

    return (
        <MainView>
            <FindBarBase left={loc("l_804")} hcmd={hfind} data={ctl} hclear={hclear} cur={opt_find} right={<Right/>} hfilter={umd.setFilter}/>
            <GridTable col={col} row={filteredRows} high={high}/>
            <WaitUmd umd={umd}/>
        </MainView>
    );
};

export {GatherView};
